/***************************************************************************************************
 *Copyright(C),2010-2016,Sumscope
 *FileName	:  BaseString.h
 *Author	:  scofined.qi
 *Version	:  1.0
 *Date		:  2016/01/12
 *Desc		:  //用于主要说明此程序文件完成的主要功能
 *Relation :
 *Others	:  //其他内容说明
 *Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
 *History	:
 * //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
 ***************************************************************************************************/
#pragma once

#include <string.h>
#include <wchar.h>

#include "../core.h"

namespace qb {
namespace base {
class S_CORE_EXPORT WideString {
 public:
  typedef WideString ThisType;
  typedef wchar_t Element;
  enum { INIT_CAPCITY = 16, npos = -1 };

 protected:
  int m_size;
  int m_capcity;
  Element* m_string;
  Element m_null[2];

 public:  // constructors
  WideString();
  WideString(const Element* str);
  WideString(const Element* str, int len);
  WideString(const ThisType& bs);
  ~WideString();

  WideString& Format(const wchar_t* format, ...);
  ThisType& operator=(const Element* str);
  ThisType& operator=(const ThisType& bs);
  ThisType& operator=(Element c);

 protected:
  void expand(int size);
  static inline int length(const Element* str) { return str ? wcslen(str) : 0; }

 public:  // operations
  void clear();
  void reset();

  ThisType& assign(Element c);
  ThisType& assign(const Element* str);
  ThisType& assign(const Element* str, int len);
  ThisType& assign(const ThisType& br);

  ThisType& append(Element c);
  ThisType& append(int count, Element c);
  ThisType& append(const Element* str);
  ThisType& append(const Element* str, int len);
  ThisType& append(const ThisType& br);

  ThisType& push_back(Element c);
  ThisType& push_back(const Element* str);
  ThisType& push_back(const Element* str, int len);
  ThisType& push_back(const ThisType& br);

  ThisType& insert(int pos, const Element* str, int len);
  ThisType& erase(int pos, int len = 1);

  ThisType& replace(int pos, int len, const Element* str, int size);
  int find(Element c, int offset = 0) const;
  int find(const Element* str, int offset = 0) const;
  int rfind(Element c, int offset) const;
  void substr(int offset, int len, ThisType& bs) const;
  ThisType substr(int offset, int len) const;
  int compare(const Element* str, int len) const;
  void swap(ThisType& bs);

 public:
  void Delete(int pos, int len) { erase(pos, len); }
  void Insert(int pos, const WideString& str) {
    insert(pos, str.c_str(), str.size());
  }
  void AppendChar(Element c) { append(c); }
  void Empty() { clear(); }
  int Find(const Element* str) { return find(str, 0); }
  WideString Left(int len) const { return substr(0, len); }
  WideString Right(int len) const {
    if (len > 0 && len < size()) return substr(size() - len, len);
    return WideString();
  }
  WideString Mid(int pos, int len) const { return substr(pos, len); }
  int CompareNoCase(const Element* str) {
    return compare(str, str ? wcslen(str) : 0);
  }
  Element GetAt(int pos) const { return at(pos); }
  bool IsEmpty() const { return size() <= 0; }

 public:  // operators
  // ThisType& operator+(const ThisType& bs){return append(bs);}
  // ThisType& operator+(const Element c){return append(c);}
  ThisType operator+(const ThisType& bs) const {
    ThisType ret(*this);
    ret.append(bs);
    return ret;
  }

  bool operator==(const ThisType& bs) const {
    return compare(bs.m_string, bs.m_size) == 0;
  }
  bool operator==(const Element* str) const {
    return compare(str, str ? length(str) : 0) == 0;
  }
  bool operator!=(const ThisType& bs) const {
    return compare(bs.m_string, bs.m_size) != 0;
  }
  bool operator!=(const Element* str) const {
    return compare(str, str ? length(str) : 0) != 0;
  }

 public:  // accessors
  const Element* c_str() const {
    return (m_string != 0 && m_size > 0) ? m_string : m_null;
  }
  Element* c_str() { return (m_string != 0 && m_size > 0) ? m_string : m_null; }
  const Element* GetString() const { return c_str(); }
  operator const Element*() const { return c_str(); }
  int size() const { return m_size; }
  int GetLength() const { return m_size; }
  int capcity() const { return m_capcity; }
  bool empty() const { return !m_string || m_size <= 0; }
  Element at(int i) const;
  Element& at(int i);
  Element operator[](int i) const { return at(i); }
  Element& operator[](int i) { return at(i); }
  static int SearchString(const Element* mainStr, int mainStrLen,
                          const Element* subStr, int subStrLen, bool ic);
};
typedef WideString UIString;

WideString& operator+=(WideString& bs, const WideString::Element* str);
WideString& operator+=(WideString& bs, const WideString& plus);
bool operator<(const WideString& left, const WideString& right);
}  // namespace base
}  // namespace qb
